home *** CD-ROM | disk | FTP | other *** search
- PAGE 64,132
- TITLE GOLD key from NUMLOCK
- NAME GOLD
- ;
- ; This program maps the NUM LOCK key (scan code 45H) to another key
- ; (default is F1, scan code 3BH) for use with Kermit emulating a DEC VTxxx
- ; terminal.
- ;
- ; Version 2.4 - June 1992
- ; Fixed spurious recognition of PAUSE key as GOLD (caused by
- ; presence of 45H in six byte sequence for PAUSE)
- ; Version 2.3 - June 1992
- ; Added facility to have modifier (CTRL, SHIFT, ALT)
- ; for chosen key
- ; Version 2.2 - February 1992
- ; Added safety checks to installation code
- ; Version 2.1 - June 1991
- ; Changed default multiplex ID to 09FH (was 0DCH) to avoid
- ; problems with some versions of the KEYB program.
- ; Version 2.0 - March 1991
- ; SHIFT and NUM LOCK acts as normal NUM LOCK
- ; ALT and NUM LOCK inverts current GOLD status
- ; Fix for problem with some clone BIOSes
- ; Fix non-detection of BIOS intercept support
- ; Use INT 09H if interrupt intercept not available
- ;
- ; Bob Eager
- ; rde@ukc.ac.uk USENET (preferred over ibmpcug)
- ; rde@ibmpcug.co.uk USENET
- ; 100016,2770 CompuServe
- ; +44 227 367270 Telephone
- ;
- ; You may distribute this program freely as long as all of the files that
- ; make up the package (see the documentation file) are kept with it (including
- ; this source file) and you don't try to make money from it either by selling
- ; it directly or incorporating it into a product you sell.
- ;
- ; Values for exit status:
- ;
- ; 0 - success
- ; 1 - could not install program
- ; 2 - no BIOS support present
- ; 3 - unsupported DOS version (< 3.0)
- ; 4 - invalid parameter
- ;
- ; Constants
- ; ---------
- ;
- CR = 0DH ; Carriage return
- LF = 0AH ; Linefeed
- TAB = 09H ; Tab
- ;
- ID = 0DCH ; Multiplex ID
- ;
- NUMSCAN = 045H ; Num Lock scan code
- P1SCAN = 0E1H ; Pause scan code byte 1
- P2SCAN = 01DH ; Pause scan code byte 2
- ;
- CSEG SEGMENT BYTE PUBLIC 'CODE'
- ;
- $BEGIN EQU $
- ;
- ORG 0100H
- ;
- ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
- ;
- SUBTTL Data areas
- PAGE+
- ;
- ; The following jump to the initialisation code also provides three bytes
- ; of storage, which are used later by the resident part of the code.
- ;
- BEGIN: JMP INIT ; jump to initialisation code
- ;
- ; Redefine storage for the above jump
- ;
- ORG BEGIN
- MBIT EQU THIS BYTE ; Make/Break bit
- ORG BEGIN+1
- ONOFF EQU THIS BYTE ; On/Off flag (0=off, initially on)
- ORG BEGIN+2
- SHFLAG EQU THIS BYTE ; Shift bits changed flag (0=No, 1=Yes)
- ;
- ; Back to normal storage allocation
- ;
- ORG BEGIN+3
- ;
- ; The following four values may be changed if required.
- ;
- ; MPID is the multiplex ID, and will only need alteration if some
- ; other TSR is using the same value. Choose another at random
- ; until it works!
- ; NEWKEY is the make code value for the key to replace NUM LOCK.
- ; Examples:
- ; 3B - F1
- ; 1E - A
- ; See a key code table (e.g. in IBM Technical Reference Manual)
- ; for the rest.
- ; MODE is used to force a particular operation mode; it is particularly
- ; useful when a BIOS says that it supports the keyboard intercept
- ; function, but doesn't.
- ; MODBIT is a way of specifying that a particular modifier key (CTRL,
- ; ALT, or SHIFT) should be forced down when the replacement
- ; keystroke is transmitted. Set as follows:
- ; 08H - ALT
- ; 04H - CTRL
- ; 02H - left SHIFT
- ; 01H - right SHIFT
- ; These bits may be combined (e.g. 0CH for CTRL+ALT). Either
- ; SHIFT key will generally work.
- ;
- MPID DB 09FH ; 102H Multiplex ID ** DO NOT MOVE **
- NEWKEY DB 03BH ; 103H Replacement key ** DO NOT MOVE **
- ;NEWKEY DB 01EH ; 103H Replacement key ** DO NOT MOVE **
- MODE DB 0 ; 104H Mode selector ** DO NOT MOVE **
- ; 00H = auto
- ; 01H = use INT 15H
- ; 02H = use INT 09H
- MODBIT DB 00H ; 105H Replacement key modifier bit
- ;MODBIT DB 08H ; 105H Replacement key modifier bit
- ; *** DO NOT MOVE ***
- SAVESH DB 0 ; Saved copy of shift flags
- STATE DB 0 ; State for PAUSE recognition
- ; ; 0 = normal scan
- ; ; 1 = after E1
- ; ; 2 = after E1 1D
- ;
- INTOFF DW ? ; Old interrupt vector offset
- INTSEG DW ? ; Old interrupt vector segment
- I2FOFF DW ? ; Old INT 2FH offset
- I2FSEG DW ? ; Old INT 2FH segment
- ;
- SUBTTL INT 2FH (multiplex) handler
- PAGE+
- ;
- ; This INT 2FH handler is hooked into the MS-DOS multiplex interrupt.
- ;
- ; Input parameters:
- ;
- ; AH = handler ID (MPID for this program)
- ; Calls with unrecognised handler IDs are passed on
- ; AL = function code
- ; 00 - get installation status
- ; 01 - get GOLD status
- ; 02 - set GOLD status
- ;
- ; Output parameters:
- ;
- ; AL = result
- ; Get installation status:
- ; FFH - Already installed
- ; Get GOLD status:
- ; 00H - OFF
- ; 01H - ON
- ; Set GOLD status:
- ; 00H - OK
- ;
- I2FHAN PROC FAR
- ;
- ASSUME CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
- ;
- CMP AH,MPID ; for this program?
- JE I2FH10 ; j if so
- JMP DWORD PTR I2FOFF ; else use old handler
- ;
- I2FH10: OR AL,AL ; AL=0, get installation status?
- JNE I2FH20 ; j if not
- MOV AL,0FFH ; indicate already installed
- IRET ; and return
- ;
- I2FH20: DEC AL ; AL=1, get GOLD status?
- JNE I2FH30 ; j if not
- MOV AL,ONOFF ; get value
- IRET ; and return
- ;
- I2FH30: DEC AL ; AL=2, set GOLD status?
- JNE I2FH40 ; j if not
- MOV ONOFF,DL ; set new value, drop through
- ;
- I2FH40: IRET ; and return
- ;
- I2FHAN ENDP
- ;
- SUBTTL INT 15H (system services) handler
- PAGE+
- ;
- ; This INT 15H handler is hooked into the BIOS system services interrupt.
- ; It is used only if the keyboard interrupt intercept capability is available
- ; in the BIOS.
- ;
- ; Input parameters:
- ; AH - function. Only 4FH (keyboard intercept) is handled;
- ; other values cause the action to be passed to the
- ; previous handler.
- ; AL - scan code for key just pressed
- ;
- ; Output parameters:
- ; AL - input scan code, or mapped version of it.
- ; CY - set to indicate that keystroke is to be processed.
- ; All other register contents are preserved.
- ;
- ASSUME CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
- ;
- I15HAN PROC FAR
- ;
- CMP AH,4FH ; keyboard intercept function?
- JE I15H10 ; j if so
- JMP DWORD PTR INTOFF ; else call old handler
- ;
- I15H10: PUSH AX ; save register
- PUSH AX ; save again
- XOR AL,AL ; set zero
- XCHG AL,SHFLAG ; get and clear flags bit
- OR AL,AL ; set condition flags
- JZ I15H15 ; j if not currently changed
- PUSH DS ; save data segment
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address it
- MOV AL,CSEG:SAVESH ; get saved keyboard flags
- MOV DS:[17H],AL ; restore them
- POP DS ; recover data segment
- I15H15: POP AX ; recover register
- CMP STATE,0 ; normal state?
- JE I15H17 ; j if so
- CMP STATE,1 ; had just one PAUSE byte?
- JE I15H16 ; j if so
- MOV STATE,0 ; else in state 2 - reset state...
- JMP I15H60 ; ...and skip checks
- ;
- I15H16: CMP AL,P2SCAN ; got second byte now?
- JE I15H18 ; j if so, => state 2
- DEC STATE ; else reset state
- JMP SHORT I15H19 ; and perform normal checks
- ;
- I15H17: CMP AL,P1SCAN ; possible PAUSE sequence?
- JNE I15H19 ; j if not, else => state 1
- ;
- I15H18: INC STATE ; update state
- JMP SHORT I15H60 ; skip checks
- ;
- I15H19: MOV AH,AL ; copy scan code
- AND AH,80H ; isolate make/break bit
- MOV MBIT,AH ; save it
- AND AL,7FH ; mask out make/break bit
- CMP AL,NUMSCAN ; NUM LOCK?
- JNE I15H60 ; j if not - just return
- ;
- ; NUM LOCK has been pressed. Check for SHIFT (retain normal action).
- ;
- PUSH DS ; save segment
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address BIOS data segment
- MOV AL,DS:[17H] ; get keyboard flags
- POP DS ; recover segment
- AND AL,0FH ; mask out lock status
- MOV AH,AL ; take copy for later comparison
- CMP ONOFF,0 ; is GOLD on?
- JE I15H20 ; j if not - do nothing here
- AND AL,03H ; mask out ALT and CTRL status
- JE I15H20 ; j if not shifted
- CMP AH,AL ; see if just SHIFT
- JE I15H60 ; if so, treat as normal NUM LOCK call
- ;
- ; Check for ALT (invert GOLD status). This needs to work whether GOLD is
- ; ON or OFF.
- ;
- I15H20: MOV AL,AH ; recover shift status bits
- AND AL,08H ; mask out CTRL and SHIFT status
- JE I15H40 ; j if not ALT - pass through
- CMP AH,AL ; see if just ALT
- JNE I15H40 ; j if not - pass through
- TEST MBIT,80H ; make operation?
- JNE I15H30 ; j if not - ignore
- XOR ONOFF,1 ; flip GOLD ON/OFF flag
- ;
- I15H30: CLC ; absorb keystroke
- POP AX ; recover register
- RETF 2 ; return, preserving flags
- ;
- I15H40: CMP ONOFF,0 ; is GOLD on?
- JE I15H60 ; j if not - do nothing
- ;
- I15H50: PUSH DS ; save data segment
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address BIOS data segment
- MOV AH,DS:[17H] ; get keyboard flags
- MOV AL,CSEG:MODBIT ; get extra modifier
- OR AL,AH ; combine with existing ones
- MOV DS:[17H],AL ; update keyboard flags
- POP DS ; recover segment
- MOV SAVESH,AH ; save old flags
- INC SHFLAG ; mark changed
- POP AX ; recover register
- MOV AL,NEWKEY ; set replacement scan code
- OR AL,MBIT ; include make/break bit, drop through
- STC ; make sure keystroke processed
- RETF 2 ; return, preserving flags
- ;
- I15H60: STC ; make sure keystroke processed
- POP AX ; recover register
- RETF 2 ; return, preserving flags
- ;
- I15HAN ENDP
- ;
- I15LEN = $ - I15HAN ; length of INT 15H handler
- ;
- SUBTTL INT 09H (keyboard interrupt) handler
- PAGE+
- ;
- ; This INT 09H handler is hooked into the keyboard interrupt vector.
- ; It is used only if the keyboard interrupt intercept facility is not
- ; available in the BIOS, and is moved in memory so that the space occupied
- ; by the INT 15H handler is not wasted.
- ;
- ; Input parameters:
- ; No explicit inputs. Implicit input from the keyboard
- ; hardware.
- ;
- ; Output parameters:
- ; No explicit outputs. Control is passed to the normal keyboard
- ; interrupt handler unless the keystroke is to be modified or
- ; absorbed. Modified keystrokes are placed into the BIOS input
- ; buffer.
- ; All registers are preserved.
- ;
- I09HAN PROC FAR
- ;
- PUSH AX ; save register
- IN AL,60H ; get next character from hardware
- PUSH AX ; save character
- XOR AL,AL ; set zero
- XCHG AL,SHFLAG ; get and clear flags bit
- OR AL,AL ; set condition flags
- JZ I09H05 ; j if not currently changed
- PUSH DS ; save data segment
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address it
- MOV AL,CSEG:SAVESH ; get saved keyboard flags
- MOV DS:[17H],AL ; restore them
- POP DS ; recover data segment
- I09H05: POP AX ; recover character
- CMP STATE,0 ; normal state?
- JE I09H07 ; j if so
- CMP STATE,1 ; had just one PAUSE byte?
- JE I09H06 ; j if so
- MOV STATE,0 ; else in state 2 - reset state...
- JMP I09H80 ; ...and skip checks
- ;
- I09H06: CMP AL,P2SCAN ; got second byte now?
- JE I09H08 ; j if so, => state 2
- DEC STATE ; else reset state
- JMP SHORT I09H09 ; and perform normal checks
- ;
- I09H07: CMP AL,P1SCAN ; possible PAUSE sequence?
- JNE I09H09 ; j if not, else => state 1
- ;
- I09H08: INC STATE ; update state
- JMP I09H80 ; skip checks
- ;
- I09H09: MOV AH,AL ; copy scan code
- AND AH,80H ; isolate make/break bit
- MOV MBIT,AH ; save it
- AND AL,7FH ; mask out make/break bit
- CMP AL,NUMSCAN ; NUM LOCK?
- JE I09H10 ; j if so
- JMP I09H80 ; else just pass on to original handler
- ;
- ; NUM LOCK has been pressed. Check for SHIFT (retain normal action).
- ;
- I09H10: PUSH DS ; save segment
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address BIOS data segment
- MOV AL,DS:[17H] ; get keyboard flags
- POP DS ; recover segment
- AND AL,0FH ; mask out lock status
- MOV AH,AL ; take copy for later comparison
- CMP ONOFF,0 ; is GOLD on?
- JE I09H20 ; j if not - do nothing here
- AND AL,03H ; mask out ALT and CTRL status
- JE I09H20 ; j if not shifted
- CMP AH,AL ; see if just SHIFT
- JNE I09H20 ; j if not
- JMP I09H80 ; else treat as normal NUM LOCK call
- ;
- ; Check for ALT (invert GOLD status). This needs to work whether GOLD is
- ; ON or OFF.
- ;
- I09H20: MOV AL,AH ; recover shift status bits
- AND AL,08H ; mask out CTRL and SHIFT status
- JE I09H30 ; j if not ALT - pass through
- CMP AH,AL ; see if just ALT
- JNE I09H30 ; j if not - pass through
- TEST MBIT,80H ; make operation?
- JNE I09H70 ; j if not - ignore
- XOR ONOFF,1 ; flip GOLD ON/OFF flag
- JMP SHORT I09H70 ; absorb keystroke and exit
- ;
- I09H30: CMP ONOFF,0 ; is GOLD on?
- JE I09H80 ; j if not - pass through
- ;
- I09H40: TEST MBIT,80H ; break code?
- JNZ I09H70 ; j if so - ignore
- PUSH DS ; save segment
- PUSH SI ; save register
- PUSH BX ; save register
- MOV AX,40H ; BIOS data segment
- MOV DS,AX ; address it
- MOV BX,DS:[1CH] ; get offset of next slot in buffer
- MOV SI,BX ; save for later
- ADD BX,2 ; advance pointer
- CMP BX,DS:[82H] ; time to wrap?
- JNZ I09H50 ; j if not
- MOV BX,DS:[80H] ; else do it
- ;
- I09H50: CMP BX,DS:[1AH] ; buffer is full?
- JZ I09H60 ; j if so - discard character
- MOV AH,NEWKEY ; set replacement scan code
- XOR AL,AL ; extended code
- MOV WORD PTR [SI],AX ; set into buffer
- MOV DS:[1CH],BX ; save updated buffer pointer
- MOV AH,DS:[17H] ; get keyboard flags
- MOV AL,CSEG:MODBIT ; get extra modifier
- OR AL,AH ; combine with existing ones
- MOV DS:[17H],AL ; update keyboard flags
- MOV CSEG:SAVESH,AH ; save old flags
- INC SHFLAG ; mark changed
- ;
- I09H60: POP BX ; recover register
- POP SI ; recover register
- POP DS ; recover segment
- ;
- ; Clear the keyboard port, acknowledging the character.
- ;
- I09H70: IN AL,61H ; get control port
- MOV AH,AL ; copy for later reset
- OR AL,80H ; set bit to acknowledge
- JMP SHORT $+2 ; wait for settle
- OUT 61H,AL ; do the acknowledge
- JMP SHORT $+2 ; wait for settle
- MOV AL,AH ; get original setting
- OUT 61H,AL ; put it back
- JMP SHORT $+2 ; wait for settle
- MOV AL,20H ; End-Of-Interrupt
- OUT 20H,AL ; send to interrupt controller
- POP AX ; recover register
- IRET ; return without calling original
- ;
- I09H80: POP AX ; recover register
- JMP DWORD PTR INTOFF ; jump to original interrupt handler
- ;
- I09HAN ENDP
- ;
- I09LEN = $ - I09HAN ; length of INT 09H handler
- ;
- SUBTTL Initialisation code
- PAGE+
- ;
- ; This is the program initialisation code. It is not present in the resident
- ; copy of the program.
- ;
- ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
- ;
- INIT: MOV ONOFF,1 ; set initial value
- MOV SHFLAG,0 ; set initial value
- MOV STATE,0 ; set initial value
- ;
- ; Select the operating mode
- ;
- CMP MODE,2 ; force INT 09H to be used?
- JE INIT50 ; j if so
- PUSH ES ; save ES
- MOV AH,0C0H ; see if keyboard intercept supported
- INT 15H ; get system configuration parameters
- JNC INIT10 ; j if configuration call supported
- POP ES ; recover ES
- JMP SHORT INIT20 ; try for INT 09H mode
- ;
- INIT10: TEST BYTE PTR ES:[BX+5],10H ; see if intercept flag set
- POP ES ; recover ES
- JNE INIT30 ; j if intercept supported - use it
- ;
- INIT20: CMP MODE,1 ; force INT 15H mode?
- JNE INIT40 ; j if not - use INT 09H mode
- LEA DX,MES0 ; 'Sorry - this machine does not...'
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AX,4C02H ; exit with error status
- INT 21H
- ;
- INIT30: MOV MODE,1 ; select INT 15H mode
- JMP SHORT INIT50 ; check DOS version now
- ;
- INIT40: MOV MODE,2 ; select INT 09H mode
- ;
- ; The INT 2FH code will work only on DOS 3.0 and above. See if it is OK
- ; to use it.
- ;
- INIT50: MOV AX,3000H ; get DOS version
- INT 21H ; returns minor in AH, major in AL
- CMP AL,3 ; see if 3 or greater
- JGE INIT60 ; j if so - OK
- LEA DX,MES1 ; 'Sorry - DOS 3.0 or above is...'
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AX,4C03H ; exit with error status
- INT 21H
- ;
- ; See if already installed
- ;
- INIT60: MOV AH,MPID ; multiplex ID
- XOR AL,AL ; function 00H
- XOR BX,BX ; zero for safety
- XOR CX,CX ; zero for safety
- XOR DX,DX ; zero for safety
- INT 2FH ; call multiplex
- PUSH CS ; restore DS in case corrupted...
- POP DS ; ...by other program
- PUSH CS ; restore ES...
- POP ES ; ...for same reason
- OR AL,AL ; see if OK to install (AL unchanged)
- JZ INIT70 ; j if so
- CMP AL,0FFH ; already installed?
- JE INIT100 ; j if so - skip installation
- LEA DX,MES2 ; 'Cannot install program'
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AX,4C01H ; exit with error status
- INT 21H
- ;
- ; Program is not installed; install it now.
- ;
- INIT70: PUSH ES ; save segment
- MOV AX,352FH ; get old INT 2FH handler
- INT 21H ; returns value in ES:BX
- MOV I2FOFF,BX ; save offset
- MOV I2FSEG,ES ; save segment
- LEA DX,I2FHAN ; point to new INT 2FH handler
- MOV AX,252FH ; set INT 2FH vector
- INT 21H ; from DS:DX
- ;
- ; Perform installation conditional on the selected mode
- ;
- CMP MODE,1 ; use INT 15H mode?
- JNE INIT80 ; j if not - set up for INT 09H
- ;
- ; Use the INT 15H code, which uses the BIOS keyboard interrupt intercept
- ;
- MOV AX,3515H ; get old INT 15H handler
- INT 21H ; returns value in ES:BX
- MOV INTOFF,BX ; save offset
- MOV INTSEG,ES ; save segment
- LEA DX,I15HAN ; point to new INT 15H handler
- MOV AX,2515H ; set INT 15H vector
- INT 21H ; from DS:DX
- POP ES ; recover segment
- MOV WORD PTR INTLEN,I15LEN ; save interrupt routine length
- JMP SHORT INIT90 ; rejoin common code
- ;
- ; Use the INT 09H code, which uses the keyboard hardware interrupt
- ;
- INIT80: MOV AX,3509H ; get old INT 09H handler
- INT 21H ; returns value in ES:BX
- MOV INTOFF,BX ; save offset
- MOV INTSEG,ES ; save segment
- LEA DX,I15HAN ; point to new INT 09H handler
- ; (where it WILL be)
- MOV AX,2509H ; set INT 09H vector
- INT 21H ; from DS:DX
- POP ES ; recover segment
- MOV CX,I09LEN ; get interrupt routine length
- MOV INTLEN,CX ; save it
- CLD ; autoincrement
- MOV SI,OFFSET I09HAN ; get address of interrupt routine
- MOV DI,OFFSET I15HAN ; where to move it
- REP MOVSB ; do so
- ;
- ; Complete installation
- ;
- INIT90: INC BYTE PTR RESFLAG ; remember to stay resident
- ;
- ; The program is now installed. Handle parameters.
- ;
- INIT100:CLD ; autoincrement
- MOV SI,81H ; offset of command tail
- MOV DI,81H ; put characters back in same place
- ;
- INIT110:LODSB ; get next command character
- CMP AL,CR ; end of command?
- JE INIT130 ; j if so
- CMP AL,'a' ; check if lower case alphabetic
- JL INIT120 ; j if not
- CMP AL,'z' ; check range
- JG INIT120 ; j if not in range
- SUB AL,'a'-'A' ; convert to upper case
- ;
- INIT120:STOSB ; return possibly modified character
- JMP INIT110 ; keep scanning
- ;
- INIT130:MOV SI,81H ; back to start of command tail
- ;
- INIT140:LODSB ; get next character
- CMP AL,' ' ; space?
- JE INIT140 ; j if so - ignore
- CMP AL,TAB ; tab?
- JE INIT140 ; j if so - ignore
- CMP AL,CR ; end of parameters?
- JE INIT150 ; j if so
- DEC SI ; point back to first non-space
- MOV BX,SI ; save pointer
- MOV CX,2 ; check for ON
- LEA DI,ON ; 'ON'
- REP CMPSB ; matched?
- JE INIT190 ; j if so
- MOV SI,BX ; recover pointer
- MOV CX,3 ; check for OFF
- LEA DI,OFF ; 'OFF'
- REP CMPSB ; matched?
- JE INIT180 ; j if so
- LEA DX,MES4 ; 'Parameter must be ON or OFF'
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AX,4C01H ; indicate error
- INT 21H ; and exit
- ;
- ; No parameter given - just report status unless initial installation
- ;
- INIT150:LEA DX,MES3 ; 'GOLD is '
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AH,MPID ; multiplex ID
- MOV AL,1 ; request status
- INT 2FH ; returns AL=0 for OFF, AL=1 for ON
- OR AL,AL ; test value
- JNZ INIT160 ; j if ON
- LEA DX,OFF ; 'OFF'
- JMP SHORT INIT170 ; join common code
- ;
- INIT160:LEA DX,ON ; 'ON'
- ;
- INIT170:MOV AH,9 ; output message
- INT 21H ; do it
- JMP SHORT INIT220 ; use common code
- ;
- INIT180:XOR DL,DL ; clear flag
- JMP SHORT INIT200 ; jump to setting code
- ;
- INIT190:MOV DL,1 ; set flag
- ;
- ; AL now contains the required GOLD setting flag. Check that the rest of
- ; the command line is blank, then if all is OK set the flag appropriately.
- ;
- INIT200:LODSB ; get next character
- CMP AL,' ' ; space?
- JE INIT200 ; j if so - ignore
- CMP AL,TAB ; tab?
- JE INIT200 ; j if so - ignore
- CMP AL,CR ; end of parameters?
- JE INIT210 ; j if so
- LEA DX,MES5 ; 'Invalid parameter'
- MOV AH,9 ; output message
- INT 21H ; do it
- MOV AX,4C04H ; indicate error
- INT 21H ; and exit
- ;
- ; The command line is OK. Set the GOLD flag.
- ;
- INIT210:MOV AH,MPID ; multiplex ID
- MOV AL,2 ; set flag from DL
- INT 2FH ; set new flag value in resident copy
- ;
- ; If this is not the first load of GOLD, just exit.
- ;
- INIT220:TEST BYTE PTR RESFLAG,1 ; make resident?
- JNE INIT230 ; j if so
- MOV AX,4C00H ; else just exit with success
- INT 21H
- ;
- ; This is the first load of GOLD; terminate and stay resident
- ;
- INIT230:MOV ES,ES:[2CH] ; get environment segment
- MOV AH,49H ; free memory for it
- INT 21H ; do it
- MOV DX,OFFSET I15HAN ; size of common part
- ADD DX,INTLEN ; add size of interrupt routine
- ADD DX,15 ; round to next paragraph
- MOV CL,4 ; amount to shift
- SHR DX,CL ; convert to paragraphs
- MOV AX,3100H ; exit with success status
- INT 21H ; and stay resident
- ;
- INTLEN DW ? ; Size of selected interrupt handler
- RESFLAG DB 0 ; Set to 1 if to stay resident
- ;
- ON DB 'ON',CR,LF,'$'
- OFF DB 'OFF',CR,LF,'$'
- MES0 DB 'Sorry - this machine does not support the GOLD utility',CR,LF
- DB 'if the interrupt intercept mode is selected'
- DB CR,LF,'$'
- MES1 DB 'Sorry - DOS 3.0 or above is required for the GOLD utility'
- DB CR,LF,'$'
- MES2 DB 'Sorry - cannot install the GOLD utility',CR,LF,'$'
- MES3 DB 'GOLD is $'
- MES4 DB 'Parameter must be ON or OFF',CR,LF,'$'
- MES5 DB 'Invalid parameter',CR,LF,'$'
- ;
- INFO DB '====GOLD version 2.4===='
- ;
- CSEG ENDS
- ;
- END BEGIN
-